home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / uemacs3.8b / part07 < prev    next >
Encoding:
Internet Message Format  |  1987-03-12  |  53.9 KB

  1. Subject:  v09i039:  MicroEMACS 3.8b, Part07/14
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: ihnp4!itivax!duncan!lawrence (Daniel Lawrence)
  6. Mod.sources: Volume 9, Issue 39
  7. Archive-name: uemacs3.8b/Part07
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 7 (of 14)."
  14. # Contents:  exec.c spawn.c window.c
  15. # Wrapped by rs@mirror on Fri Mar 13 13:24:22 1987
  16. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  17. echo shar: Extracting \"exec.c\" \(16413 characters\)
  18. if test -f exec.c ; then 
  19.   echo shar: Will not over-write existing file \"exec.c\"
  20. else
  21. sed "s/^X//" >exec.c <<'END_OF_exec.c'
  22. X/*    This file is for functions dealing with execution of
  23. X    commands, command lines, buffers, files and startup files
  24. X
  25. X    written 1986 by Daniel Lawrence                */
  26. X
  27. X#include    <stdio.h>
  28. X#include    "estruct.h"
  29. X#include    "edef.h"
  30. X
  31. X#if    MEGAMAX & ST520
  32. Xoverlay    "exec"
  33. X#endif
  34. X
  35. X#if    DEBUGM
  36. Xchar outline[NSTRING];        /* global string to hold debug line text */
  37. X#endif
  38. X
  39. X/* namedcmd:    execute a named command even if it is not bound */
  40. X
  41. Xnamedcmd(f, n)
  42. X
  43. Xint f, n;    /* command arguments [passed through to command executed] */
  44. X
  45. X{
  46. X    register (*kfunc)();    /* ptr to the requexted function to bind to */
  47. X    int (*getname())();
  48. X
  49. X    /* prompt the user to type a named command */
  50. X    mlwrite(": ");
  51. X
  52. X    /* and now get the function name to execute */
  53. X    kfunc = getname();
  54. X    if (kfunc == NULL) {
  55. X        mlwrite("[No such function]");
  56. X        return(FALSE);
  57. X    }
  58. X
  59. X    /* and then execute the command */
  60. X    return((*kfunc)(f, n));
  61. X}
  62. X
  63. X/*    execcmd:    Execute a command line command to be typed in
  64. X            by the user                    */
  65. X
  66. Xexeccmd(f, n)
  67. X
  68. Xint f, n;    /* default Flag and Numeric argument */
  69. X
  70. X{
  71. X    register int status;        /* status return */
  72. X    char cmdstr[NSTRING];        /* string holding command to execute */
  73. X
  74. X    /* get the line wanted */
  75. X    if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
  76. X        return(status);
  77. X
  78. X    execlevel = 0;
  79. X    return(docmd(cmdstr));
  80. X}
  81. X
  82. X/*    docmd:    take a passed string as a command line and translate
  83. X        it to be executed as a command. This function will be
  84. X        used by execute-command-line and by all source and
  85. X        startup files. Lastflag/thisflag is also updated.
  86. X
  87. X    format of the command line is:
  88. X
  89. X        {# arg} <command-name> {<argument string(s)>}
  90. X
  91. X    Directives start with a "!" and include:
  92. X
  93. X    !endm        End a macro
  94. X    !if (cond)    conditional execution
  95. X    !else
  96. X    !endif
  97. X    !return        Return (terminating current macro)
  98. X    !goto <label>    Jump to a label in the current macro
  99. X
  100. X    Line Labels begin with a "*" in column 1, like:
  101. X
  102. X    *LBL01
  103. X*/
  104. X
  105. Xdocmd(cline)
  106. X
  107. Xchar *cline;    /* command line to execute */
  108. X
  109. X{
  110. X    register int f;        /* default argument flag */
  111. X    register int n;        /* numeric repeat value */
  112. X    register int i;
  113. X    int (*fnc)();        /* function to execute */
  114. X    int status;        /* return status of function */
  115. X    int oldcle;        /* old contents of clexec flag */
  116. X    int llen;        /* length of cline */
  117. X    int force;        /* force TRUE result? */
  118. X    char *tmp;        /* tmp pointer into cline */
  119. X    struct LINE *lp;    /* a line pointer */
  120. X    char *oldestr;        /* original exec string */
  121. X    char token[NSTRING];    /* next token off of command line */
  122. X    int (*fncmatch())();
  123. X#if    DEBUGM
  124. X    /* if $debug == TRUE, every line to execute
  125. X       gets echoed and a key needs to be pressed to continue
  126. X       ^G will abort the command */
  127. X    register char *sp;    /* pointer into buf to expand %s */
  128. X
  129. X    if (macbug) {
  130. X        strcpy(outline, "<<<");
  131. X#if    1    /* debug if levels */
  132. X        strcat(outline, itoa(execlevel));
  133. X        strcat(outline, ":");
  134. X#endif
  135. X        strcat(outline, cline);
  136. X        strcat(outline, ">>>");
  137. X
  138. X        /* change all '%' to ':' so mlwrite won't expect arguments */
  139. X        sp = outline;
  140. X        while (*sp) {
  141. X            if (*sp++ == '%')
  142. X                *(sp-1) = ':';
  143. X        }
  144. X
  145. X        /* write out the debug line */
  146. X        mlwrite(outline);
  147. X        update(TRUE);
  148. X
  149. X        /* and get the keystroke */
  150. X        if (tgetc() == 7) {
  151. X            mlwrite("[Macro aborted]");
  152. X            return(FALSE);
  153. X        }
  154. X    }
  155. X#endif
  156. X        
  157. X    /* dump comments and labels here */
  158. X    if (*cline == ';' || *cline == '*')
  159. X        return(TRUE);
  160. X
  161. X    /* eat leading spaces */
  162. X    while (*cline == ' ' || *cline == '\t')
  163. X        ++cline;
  164. X
  165. X    /* check to see if this line turns macro storage off */
  166. X    if (cline[0] == '!' && strncmp(&cline[1], "endm", 4) == 0) {
  167. X        mstore = FALSE;
  168. X        bstore = NULL;
  169. X        return(TRUE);
  170. X    }
  171. X
  172. X    /* if macro store is on, just salt this away */
  173. X    if (mstore) {
  174. X        /* allocate the space for the line */
  175. X        llen = strlen(cline);
  176. X        if ((lp=lalloc(llen)) == NULL) {
  177. X            mlwrite("Out of memory while storing macro");
  178. X            return (FALSE);
  179. X        }
  180. X
  181. X        /* copy the text into the new line */
  182. X        for (i=0; i<llen; ++i)
  183. X            lputc(lp, i, cline[i]);
  184. X
  185. X        /* attach the line to the end of the buffer */
  186. X               bstore->b_linep->l_bp->l_fp = lp;
  187. X        lp->l_bp = bstore->b_linep->l_bp;
  188. X        bstore->b_linep->l_bp = lp;
  189. X        lp->l_fp = bstore->b_linep;
  190. X        return (TRUE);
  191. X    }
  192. X    
  193. X    force = FALSE;
  194. X    oldestr = execstr;    /* save last ptr to string to execute */
  195. X    execstr = cline;    /* and set this one as current */
  196. X
  197. X    /* process directives */
  198. X    if (*cline == '!') {
  199. X        /* save directive location and skip it */
  200. X        tmp = cline;
  201. X        while (*execstr && *execstr != ' ' && *execstr != '\t')
  202. X            ++execstr;
  203. X
  204. X        if (tmp[1] == 'f' && tmp[2] == 'o') {
  205. X            force = TRUE;
  206. X            goto do001;
  207. X
  208. X        } else if (tmp[1] == 'i' && tmp[2] == 'f') {
  209. X
  210. X            /* IF directive */
  211. X            /* grab the value of the logical exp */
  212. X            if (execlevel == 0) {
  213. X                if ((status = macarg(token)) != TRUE) {
  214. X                    execstr = oldestr;
  215. X                    return(status);
  216. X                }
  217. X                status = stol(token);
  218. X            } else
  219. X                status = TRUE;
  220. X
  221. X            if (status) {
  222. X
  223. X                /* IF (TRUE) */
  224. X                if (execlevel != 0)
  225. X                    ++execlevel;
  226. X            } else {
  227. X
  228. X                /* IF (FALSE) */
  229. X                ++execlevel;
  230. X            }
  231. X
  232. X        } else if (tmp[1] == 'e' && tmp[2] == 'l') {
  233. X
  234. X            /* ELSE directive */
  235. X            if (execlevel == 1)
  236. X                --execlevel;
  237. X            else if (execlevel == 0 )
  238. X                ++execlevel;
  239. X
  240. X        } else if (tmp[1] == 'e' && tmp[2] == 'n') {
  241. X
  242. X            /* ENDIF directive */
  243. X            if (execlevel)
  244. X                --execlevel;
  245. X
  246. X        } else if (tmp[1] == 'r' && tmp[2] == 'e') {
  247. X
  248. X            /* RETURN directive */
  249. X            execstr = oldestr;
  250. X            return(RET);
  251. X
  252. X        } else if (tmp[1] == 'g' && tmp[2] == 'o') {
  253. X
  254. X            /* GOTO directive */
  255. X            /* .....only if we are currently executing */
  256. X            if (execlevel) {
  257. X                execstr = oldestr;
  258. X                return(TRUE);
  259. X            }
  260. X
  261. X            while (*execstr == ' ' || *execstr == '\t')
  262. X                ++execstr;
  263. X            strncpy(golabel, execstr, NPAT - 1);
  264. X            return(GOLINE);
  265. X
  266. X        } else {
  267. X            mlwrite("%%Unknown Directive");
  268. X            return(FALSE);
  269. X        }
  270. X
  271. X        /* restore execstr and exit */
  272. X        execstr = oldestr;
  273. X        return(TRUE);
  274. X    }
  275. X
  276. Xdo001:    /* if we are scanning and not executing..go back here */
  277. X    if (execlevel) {
  278. X        execstr = oldestr;
  279. X        return(TRUE);
  280. X    }
  281. X
  282. X    /* first set up the default command values */
  283. X    f = FALSE;
  284. X    n = 1;
  285. X    lastflag = thisflag;
  286. X    thisflag = 0;
  287. X
  288. X    if ((status = macarg(token)) != TRUE) {    /* and grab the first token */
  289. X        execstr = oldestr;
  290. X        return(status);
  291. X    }
  292. X
  293. X    /* process leadin argument */
  294. X    if (gettyp(token) != TKCMD) {
  295. X        f = TRUE;
  296. X        n = atoi(getval(token));
  297. X
  298. X        /* and now get the command to execute */
  299. X        if ((status = macarg(token)) != TRUE) {
  300. X            execstr = oldestr;
  301. X            return(status);    
  302. X        }    
  303. X    }
  304. X
  305. X    /* and match the token to see if it exists */
  306. X    if ((fnc = fncmatch(token)) == NULL) {
  307. X        mlwrite("[No such Function]");
  308. X        execstr = oldestr;
  309. X        return(FALSE);
  310. X    }
  311. X    
  312. X    /* save the arguments and go execute the command */
  313. X    oldcle = clexec;        /* save old clexec flag */
  314. X    clexec = TRUE;            /* in cline execution */
  315. X    status = (*fnc)(f, n);        /* call the function */
  316. X    cmdstatus = status;        /* save the status */
  317. X    if (force)            /* force the status */
  318. X        status = TRUE;
  319. X    clexec = oldcle;        /* restore clexec flag */
  320. X    execstr = oldestr;
  321. X    return(status);
  322. X}
  323. X
  324. X/* token:    chop a token off a string
  325. X        return a pointer past the token
  326. X*/
  327. X
  328. Xchar *token(src, tok)
  329. X
  330. Xchar *src, *tok;    /* source string, destination token string */
  331. X
  332. X{
  333. X    register int quotef;    /* is the current string quoted? */
  334. X
  335. X    /* first scan past any whitespace in the source string */
  336. X    while (*src == ' ' || *src == '\t')
  337. X        ++src;
  338. X
  339. X    /* scan through the source string */
  340. X    quotef = FALSE;
  341. X    while (*src) {
  342. X        /* process special characters */
  343. X        if (*src == '~') {
  344. X            ++src;
  345. X            if (*src == 0)
  346. X                break;
  347. X            switch (*src++) {
  348. X                case 'r':    *tok++ = 13; break;
  349. X                case 'n':    *tok++ = 10; break;
  350. X                case 't':    *tok++ = 9;  break;
  351. X                case 'b':    *tok++ = 8;  break;
  352. X                case 'f':    *tok++ = 12; break;
  353. X                default:    *tok++ = *(src-1);
  354. X            }
  355. X        } else {
  356. X            /* check for the end of the token */
  357. X            if (quotef) {
  358. X                if (*src == '"')
  359. X                    break;
  360. X            } else {
  361. X                if (*src == ' ' || *src == '\t')
  362. X                    break;
  363. X            }
  364. X
  365. X            /* set quote mode if qoute found */
  366. X            if (*src == '"')
  367. X                quotef = TRUE;
  368. X
  369. X            /* record the character */
  370. X            *tok++ = *src++;
  371. X        }
  372. X    }
  373. X
  374. X    /* terminate the token and exit */
  375. X    if (*src)
  376. X        ++src;
  377. X    *tok = 0;
  378. X    return(src);
  379. X}
  380. X
  381. Xmacarg(tok)    /* get a macro line argument */
  382. X
  383. Xchar *tok;    /* buffer to place argument */
  384. X
  385. X{
  386. X    int savcle;    /* buffer to store original clexec */
  387. X    int status;
  388. X
  389. X    savcle = clexec;    /* save execution mode */
  390. X    clexec = TRUE;        /* get the argument */
  391. X    status = nextarg("", tok, NSTRING, ctoec('\n'));
  392. X    clexec = savcle;    /* restore execution mode */
  393. X    return(status);
  394. X}
  395. X
  396. X/*    nextarg:    get the next argument    */
  397. X
  398. Xnextarg(prompt, buffer, size, terminator)
  399. X
  400. Xchar *prompt;        /* prompt to use if we must be interactive */
  401. Xchar *buffer;        /* buffer to put token into */
  402. Xchar *size;        /* size of the buffer */
  403. Xint terminator;        /* terminating char to be used on interactive fetch */
  404. X
  405. X{
  406. X    /* if we are interactive, go get it! */
  407. X    if (clexec == FALSE)
  408. X        return(getstring(prompt, buffer, size, terminator));
  409. X
  410. X    /* grab token and advance past */
  411. X    execstr = token(execstr, buffer);
  412. X
  413. X    /* evaluate it */
  414. X    strcpy(buffer, getval(buffer));
  415. X    return(TRUE);
  416. X}
  417. X
  418. X/*    storemac:    Set up a macro buffer and flag to store all
  419. X            executed command lines there            */
  420. X
  421. Xstoremac(f, n)
  422. X
  423. Xint f;        /* default flag */
  424. Xint n;        /* macro number to use */
  425. X
  426. X{
  427. X    register struct BUFFER *bp;    /* pointer to macro buffer */
  428. X    char bname[NBUFN];        /* name of buffer to use */
  429. X
  430. X    /* must have a numeric argument to this function */
  431. X    if (f == FALSE) {
  432. X        mlwrite("No macro specified");
  433. X        return(FALSE);
  434. X    }
  435. X
  436. X    /* range check the macro number */
  437. X    if (n < 1 || n > 40) {
  438. X        mlwrite("Macro number out of range");
  439. X        return(FALSE);
  440. X    }
  441. X
  442. X    /* construct the macro buffer name */
  443. X    strcpy(bname, "[Macro xx]");
  444. X    bname[7] = '0' + (n / 10);
  445. X    bname[8] = '0' + (n % 10);
  446. X
  447. X    /* set up the new macro buffer */
  448. X    if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
  449. X        mlwrite("Can not create macro");
  450. X        return(FALSE);
  451. X    }
  452. X
  453. X    /* and make sure it is empty */
  454. X    bclear(bp);
  455. X
  456. X    /* and set the macro store pointers to it */
  457. X    mstore = TRUE;
  458. X    bstore = bp;
  459. X    return(TRUE);
  460. X}
  461. X
  462. X/*    execbuf:    Execute the contents of a buffer of commands    */
  463. X
  464. Xexecbuf(f, n)
  465. X
  466. Xint f, n;    /* default flag and numeric arg */
  467. X
  468. X{
  469. X        register BUFFER *bp;        /* ptr to buffer to execute */
  470. X        register int status;        /* status return */
  471. X        char bufn[NBUFN];        /* name of buffer to execute */
  472. X
  473. X    /* find out what buffer the user wants to execute */
  474. X        if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
  475. X                return(status);
  476. X
  477. X    /* find the pointer to that buffer */
  478. X        if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
  479. X        mlwrite("No such buffer");
  480. X                return(FALSE);
  481. X        }
  482. X
  483. X    /* and now execute it as asked */
  484. X    while (n-- > 0)
  485. X        if ((status = dobuf(bp)) != TRUE)
  486. X            return(status);
  487. X    return(TRUE);
  488. X}
  489. X
  490. X/*    dobuf:    execute the contents of the buffer pointed to
  491. X        by the passed BP                */
  492. X
  493. Xdobuf(bp)
  494. X
  495. XBUFFER *bp;    /* buffer to execute */
  496. X
  497. X{
  498. X        register int status;        /* status return */
  499. X    register LINE *lp;        /* pointer to line to execute */
  500. X    register LINE *hlp;        /* pointer to line header */
  501. X    register LINE *glp;        /* line to goto */
  502. X    register int linlen;        /* length of line to execute */
  503. X    register WINDOW *wp;        /* ptr to windows to scan */
  504. X    char *eline;            /* text of line to execute */
  505. X
  506. X    /* clear IF level flags */
  507. X    execlevel = 0;
  508. X
  509. X    /* starting at the beginning of the buffer */
  510. X    hlp = bp->b_linep;
  511. X    lp = hlp->l_fp;
  512. X    while (lp != hlp) {
  513. X        /* allocate eline and copy macro line to it */
  514. X        linlen = lp->l_used;
  515. X        if ((eline = malloc(linlen+1)) == NULL) {
  516. X            mlwrite("%%Out of Memory during macro execution");
  517. X            return(FALSE);
  518. X        }
  519. X        strncpy(eline, lp->l_text, linlen);
  520. X        eline[linlen] = 0;    /* make sure it ends */
  521. X
  522. X        /* trim leading whitespace */
  523. X        while (eline[0] == ' ' || eline[0] == '\t')
  524. X            strcpy(eline, &eline[1]);
  525. X
  526. X        /* if it is not a comment, execute it */
  527. X        if (eline[0] != 0 && eline[0] != ';') {
  528. X            status = docmd(eline);
  529. X
  530. X            /* if it is a !GOTO directive, deal with it */
  531. X            if (status == GOLINE) {
  532. X                linlen = strlen(golabel);
  533. X                glp = hlp->l_fp;
  534. X                while (glp != hlp) {
  535. X                    if (*glp->l_text == '*' &&
  536. X                        (strncmp(&glp->l_text[1], golabel,
  537. X                                linlen) == 0)) {
  538. X                        lp = glp;
  539. X                        status = TRUE;
  540. X                    }
  541. X                glp = glp->l_fp;
  542. X                }
  543. X            }
  544. X
  545. X            if (status == GOLINE) {
  546. X                mlwrite("%%No such label");
  547. X                return(FALSE);
  548. X            }
  549. X
  550. X            /* if it is a !RETURN directive...do so */
  551. X            if (status == RET) {
  552. X                free(eline);
  553. X                break;
  554. X            }
  555. X
  556. X            /* check for a command error */
  557. X            if (status != TRUE) {
  558. X                /* look if buffer is showing */
  559. X                wp = wheadp;
  560. X                while (wp != NULL) {
  561. X                    if (wp->w_bufp == bp) {
  562. X                        /* and point it */
  563. X                        wp->w_dotp = lp;
  564. X                        wp->w_doto = 0;
  565. X                        wp->w_flag |= WFHARD;
  566. X                    }
  567. X                    wp = wp->w_wndp;
  568. X                }
  569. X                /* in any case set the buffer . */
  570. X                bp->b_dotp = lp;
  571. X                bp->b_doto = 0;
  572. X                free(eline);
  573. X                execlevel = 0;
  574. X                return(status);
  575. X            }
  576. X        }
  577. X
  578. X        /* on to the next line */
  579. X        free(eline);
  580. X        lp = lp->l_fp;
  581. X    }
  582. X
  583. X    /* exit the current function */
  584. X    execlevel = 0;
  585. X        return(TRUE);
  586. X}
  587. X
  588. Xexecfile(f, n)    /* execute a series of commands in a file
  589. X*/
  590. X
  591. Xint f, n;    /* default flag and numeric arg to pass on to file */
  592. X
  593. X{
  594. X    register int status;    /* return status of name query */
  595. X    char *fname[NSTRING];    /* name of file to execute */
  596. X
  597. X    if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
  598. X        return(status);
  599. X
  600. X    /* otherwise, execute it */
  601. X    while (n-- > 0)
  602. X        if ((status=dofile(fname)) != TRUE)
  603. X            return(status);
  604. X
  605. X    return(TRUE);
  606. X}
  607. X
  608. X/*    dofile:    yank a file into a buffer and execute it
  609. X        if there are no errors, delete the buffer on exit */
  610. X
  611. Xdofile(fname)
  612. X
  613. Xchar *fname;    /* file name to execute */
  614. X
  615. X{
  616. X    register BUFFER *bp;    /* buffer to place file to exeute */
  617. X    register BUFFER *cb;    /* temp to hold current buf while we read */
  618. X    register int status;    /* results of various calls */
  619. X    char bname[NBUFN];    /* name of buffer */
  620. X
  621. X    makename(bname, fname);        /* derive the name of the buffer */
  622. X    if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
  623. X        return(FALSE);
  624. X
  625. X    bp->b_mode = MDVIEW;    /* mark the buffer as read only */
  626. X    cb = curbp;        /* save the old buffer */
  627. X    curbp = bp;        /* make this one current */
  628. X    /* and try to read in the file to execute */
  629. X    if ((status = readin(fname, FALSE)) != TRUE) {
  630. X        curbp = cb;    /* restore the current buffer */
  631. X        return(status);
  632. X    }
  633. X
  634. X    /* go execute it! */
  635. X    curbp = cb;        /* restore the current buffer */
  636. X    if ((status = dobuf(bp)) != TRUE)
  637. X        return(status);
  638. X
  639. X    /* if not displayed, remove the now unneeded buffer and exit */
  640. X    if (bp->b_nwnd == 0)
  641. X        zotbuf(bp);
  642. X    return(TRUE);
  643. X}
  644. X
  645. X/*    cbuf:    Execute the contents of a numbered buffer    */
  646. X
  647. Xcbuf(f, n, bufnum)
  648. X
  649. Xint f, n;    /* default flag and numeric arg */
  650. Xint bufnum;    /* number of buffer to execute */
  651. X
  652. X{
  653. X        register BUFFER *bp;        /* ptr to buffer to execute */
  654. X        register int status;        /* status return */
  655. X    static char bufname[] = "[Macro xx]";
  656. X
  657. X    /* make the buffer name */
  658. X    bufname[7] = '0' + (bufnum / 10);
  659. X    bufname[8] = '0' + (bufnum % 10);
  660. X
  661. X    /* find the pointer to that buffer */
  662. X        if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
  663. X            mlwrite("Macro not defined");
  664. X                return(FALSE);
  665. X        }
  666. X
  667. X    /* and now execute it as asked */
  668. X    while (n-- > 0)
  669. X        if ((status = dobuf(bp)) != TRUE)
  670. X            return(status);
  671. X    return(TRUE);
  672. X}
  673. X
  674. Xcbuf1(f, n)
  675. X
  676. X{
  677. X    cbuf(f, n, 1);
  678. X}
  679. X
  680. Xcbuf2(f, n)
  681. X
  682. X{
  683. X    cbuf(f, n, 2);
  684. X}
  685. X
  686. Xcbuf3(f, n)
  687. X
  688. X{
  689. X    cbuf(f, n, 3);
  690. X}
  691. X
  692. Xcbuf4(f, n)
  693. X
  694. X{
  695. X    cbuf(f, n, 4);
  696. X}
  697. X
  698. Xcbuf5(f, n)
  699. X
  700. X{
  701. X    cbuf(f, n, 5);
  702. X}
  703. X
  704. Xcbuf6(f, n)
  705. X
  706. X{
  707. X    cbuf(f, n, 6);
  708. X}
  709. X
  710. Xcbuf7(f, n)
  711. X
  712. X{
  713. X    cbuf(f, n, 7);
  714. X}
  715. X
  716. Xcbuf8(f, n)
  717. X
  718. X{
  719. X    cbuf(f, n, 8);
  720. X}
  721. X
  722. Xcbuf9(f, n)
  723. X
  724. X{
  725. X    cbuf(f, n, 9);
  726. X}
  727. X
  728. Xcbuf10(f, n)
  729. X
  730. X{
  731. X    cbuf(f, n, 10);
  732. X}
  733. X
  734. Xcbuf11(f, n)
  735. X
  736. X{
  737. X    cbuf(f, n, 11);
  738. X}
  739. X
  740. Xcbuf12(f, n)
  741. X
  742. X{
  743. X    cbuf(f, n, 12);
  744. X}
  745. X
  746. Xcbuf13(f, n)
  747. X
  748. X{
  749. X    cbuf(f, n, 13);
  750. X}
  751. X
  752. Xcbuf14(f, n)
  753. X
  754. X{
  755. X    cbuf(f, n, 14);
  756. X}
  757. X
  758. Xcbuf15(f, n)
  759. X
  760. X{
  761. X    cbuf(f, n, 15);
  762. X}
  763. X
  764. Xcbuf16(f, n)
  765. X
  766. X{
  767. X    cbuf(f, n, 16);
  768. X}
  769. X
  770. Xcbuf17(f, n)
  771. X
  772. X{
  773. X    cbuf(f, n, 17);
  774. X}
  775. X
  776. Xcbuf18(f, n)
  777. X
  778. X{
  779. X    cbuf(f, n, 18);
  780. X}
  781. X
  782. Xcbuf19(f, n)
  783. X
  784. X{
  785. X    cbuf(f, n, 19);
  786. X}
  787. X
  788. Xcbuf20(f, n)
  789. X
  790. X{
  791. X    cbuf(f, n, 20);
  792. X}
  793. X
  794. Xcbuf21(f, n)
  795. X
  796. X{
  797. X    cbuf(f, n, 21);
  798. X}
  799. X
  800. Xcbuf22(f, n)
  801. X
  802. X{
  803. X    cbuf(f, n, 22);
  804. X}
  805. X
  806. Xcbuf23(f, n)
  807. X
  808. X{
  809. X    cbuf(f, n, 23);
  810. X}
  811. X
  812. Xcbuf24(f, n)
  813. X
  814. X{
  815. X    cbuf(f, n, 24);
  816. X}
  817. X
  818. Xcbuf25(f, n)
  819. X
  820. X{
  821. X    cbuf(f, n, 25);
  822. X}
  823. X
  824. Xcbuf26(f, n)
  825. X
  826. X{
  827. X    cbuf(f, n, 26);
  828. X}
  829. X
  830. Xcbuf27(f, n)
  831. X
  832. X{
  833. X    cbuf(f, n, 27);
  834. X}
  835. X
  836. Xcbuf28(f, n)
  837. X
  838. X{
  839. X    cbuf(f, n, 28);
  840. X}
  841. X
  842. Xcbuf29(f, n)
  843. X
  844. X{
  845. X    cbuf(f, n, 29);
  846. X}
  847. X
  848. Xcbuf30(f, n)
  849. X
  850. X{
  851. X    cbuf(f, n, 30);
  852. X}
  853. X
  854. Xcbuf31(f, n)
  855. X
  856. X{
  857. X    cbuf(f, n, 31);
  858. X}
  859. X
  860. Xcbuf32(f, n)
  861. X
  862. X{
  863. X    cbuf(f, n, 32);
  864. X}
  865. X
  866. Xcbuf33(f, n)
  867. X
  868. X{
  869. X    cbuf(f, n, 33);
  870. X}
  871. X
  872. Xcbuf34(f, n)
  873. X
  874. X{
  875. X    cbuf(f, n, 34);
  876. X}
  877. X
  878. Xcbuf35(f, n)
  879. X
  880. X{
  881. X    cbuf(f, n, 35);
  882. X}
  883. X
  884. Xcbuf36(f, n)
  885. X
  886. X{
  887. X    cbuf(f, n, 36);
  888. X}
  889. X
  890. Xcbuf37(f, n)
  891. X
  892. X{
  893. X    cbuf(f, n, 37);
  894. X}
  895. X
  896. Xcbuf38(f, n)
  897. X
  898. X{
  899. X    cbuf(f, n, 38);
  900. X}
  901. X
  902. Xcbuf39(f, n)
  903. X
  904. X{
  905. X    cbuf(f, n, 39);
  906. X}
  907. X
  908. Xcbuf40(f, n)
  909. X
  910. X{
  911. X    cbuf(f, n, 40);
  912. X}
  913. X
  914. X
  915. END_OF_exec.c
  916. if test 16413 -ne `wc -c <exec.c`; then
  917.     echo shar: \"exec.c\" unpacked with wrong size!
  918. fi
  919. # end of overwriting check
  920. fi
  921. echo shar: Extracting \"spawn.c\" \(16459 characters\)
  922. if test -f spawn.c ; then 
  923.   echo shar: Will not over-write existing file \"spawn.c\"
  924. else
  925. sed "s/^X//" >spawn.c <<'END_OF_spawn.c'
  926. X/*    Spawn:    various DOS access commands
  927. X        for MicroEMACS
  928. X*/
  929. X
  930. X#include        <stdio.h>
  931. X#include    "estruct.h"
  932. X#include        "edef.h"
  933. X
  934. X#if     AMIGA
  935. X#define  NEW   1006
  936. X#endif
  937. X
  938. X#if        ST520
  939. X#include <osbind.h>
  940. X#include <string.h>
  941. X#define LOAD_EXEC 0     /* load and execute the program */
  942. Xchar    *STcmd,        /* the command filename & path  */
  943. X    *STargs,    /* command args (if any)        */
  944. X    *STenv,        /* environment                  */
  945. X    *STwork;    /* work area            */
  946. X#endif
  947. X
  948. X#if     VMS
  949. X#define EFN     0                               /* Event flag.          */
  950. X
  951. X#include        <ssdef.h>                       /* Random headers.      */
  952. X#include        <stsdef.h>
  953. X#include        <descrip.h>
  954. X#include        <iodef.h>
  955. X
  956. Xextern  int     oldmode[3];                     /* In "termio.c"        */
  957. Xextern  int     newmode[3];                     /* In "termio.c"        */
  958. Xextern  short   iochan;                         /* In "termio.c"        */
  959. X#endif
  960. X
  961. X#if     V7 | USG | BSD
  962. X#include        <signal.h>
  963. Xextern int vttidy();
  964. X#endif
  965. X
  966. X#if    MSDOS & MSC
  967. X#include    <process.h>
  968. X#define    system(a)    spawnlp(P_WAIT, a, NULL)
  969. X#endif
  970. X
  971. X/*
  972. X * Create a subjob with a copy of the command intrepreter in it. When the
  973. X * command interpreter exits, mark the screen as garbage so that you do a full
  974. X * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  975. X * Under some (unknown) condition, you don't get one free when DCL starts up.
  976. X */
  977. Xspawncli(f, n)
  978. X{
  979. X#if     AMIGA
  980. X        long newcli;
  981. X#endif
  982. X
  983. X#if     V7 | USG | BSD
  984. X        register char *cp;
  985. X        char    *getenv();
  986. X#endif
  987. X
  988. X    /* don't allow this command if restricted */
  989. X    if (restflag)
  990. X        return(resterr());
  991. X
  992. X#if    AMIGA
  993. X        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
  994. X        mlwrite("[Starting new CLI]");
  995. X        sgarbf = TRUE;
  996. X        Execute("", newcli, 0);
  997. X        Close(newcli);
  998. X        return(TRUE);
  999. X#endif
  1000. X
  1001. X#if     VMS
  1002. X        movecursor(term.t_nrow, 0);             /* In last line.        */
  1003. X        mlputs("[Starting DCL]\r\n");
  1004. X        TTflush();                          /* Ignore "ttcol".      */
  1005. X        sgarbf = TRUE;
  1006. X        return (sys(NULL));                     /* NULL => DCL.         */
  1007. X#endif
  1008. X#if     CPM
  1009. X        mlwrite("Not in CP/M-86");
  1010. X#endif
  1011. X#if    ST520
  1012. X    mlwrite("Not in TOS");
  1013. X#endif
  1014. X#if     MSDOS & AZTEC
  1015. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  1016. X        TTflush();
  1017. X    TTkclose();
  1018. X    system("command.com");
  1019. X    TTkopen();
  1020. X        sgarbf = TRUE;
  1021. X        return(TRUE);
  1022. X#endif
  1023. X#if     MSDOS & LATTICE
  1024. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  1025. X        TTflush();
  1026. X    TTkclose();
  1027. X        sys("\\command.com", "");               /* Run CLI.             */
  1028. X    TTkopen();
  1029. X        sgarbf = TRUE;
  1030. X        return(TRUE);
  1031. X#endif
  1032. X#if     V7 | USG | BSD
  1033. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  1034. X        TTflush();
  1035. X        TTclose();                              /* stty to old settings */
  1036. X        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
  1037. X                system(cp);
  1038. X        else
  1039. X#if    BSD
  1040. X                system("exec /bin/csh");
  1041. X#else
  1042. X                system("exec /bin/sh");
  1043. X#endif
  1044. X        sgarbf = TRUE;
  1045. X        sleep(2);
  1046. X        TTopen();
  1047. X        return(TRUE);
  1048. X#endif
  1049. X}
  1050. X
  1051. X#if    BSD
  1052. X
  1053. Xbktoshell()        /* suspend MicroEMACS and wait to wake up */
  1054. X{
  1055. X    int pid;
  1056. X
  1057. X    vttidy();
  1058. X    pid = getpid();
  1059. X    kill(pid,SIGTSTP);
  1060. X}
  1061. X
  1062. Xrtfrmshell()
  1063. X{
  1064. X    TTopen();
  1065. X    curwp->w_flag = WFHARD;
  1066. X    sgarbf = TRUE;
  1067. X}
  1068. X#endif
  1069. X
  1070. X/*
  1071. X * Run a one-liner in a subjob. When the command returns, wait for a single
  1072. X * character to be typed, then mark the screen as garbage so a full repaint is
  1073. X * done. Bound to "C-X !".
  1074. X */
  1075. Xspawn(f, n)
  1076. X{
  1077. X        register int    s;
  1078. X        char            line[NLINE];
  1079. X
  1080. X#if    ST520
  1081. X    int i,j,k;
  1082. X    char *sptr,*tptr;
  1083. X#endif
  1084. X
  1085. X#if     AMIGA
  1086. X        long newcli;
  1087. X#endif
  1088. X
  1089. X    /* don't allow this command if restricted */
  1090. X    if (restflag)
  1091. X        return(resterr());
  1092. X
  1093. X#if    AMIGA
  1094. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  1095. X                return (s);
  1096. X        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
  1097. X        Execute(line,0,newcli);
  1098. X        Close(newcli);
  1099. X        tgetc();     /* Pause.               */
  1100. X        sgarbf = TRUE;
  1101. X        return(TRUE);
  1102. X#endif
  1103. X#if     ST520
  1104. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  1105. X                return(s);
  1106. X    movecursor(term.t_nrow - 1, 0);
  1107. X    TTclose();
  1108. X/*
  1109. X * break the line into the command and its args
  1110. X * be cute about it, if there is no '.' in the filename, try
  1111. X * to find .prg, .tos or .ttp in that order
  1112. X * in any case check to see that the file exists before we run 
  1113. X * amok
  1114. X */
  1115. X    STenv = NULL;
  1116. X    if((tptr = index(&line[0],' ')) == NULL) { /* no args */
  1117. X        STcmd = (char *)malloc(strlen(line) + 1);
  1118. X        strcpy(STcmd,line);
  1119. X        STargs = NULL;
  1120. X    }
  1121. X    else {  /* seperate out the args from the command */
  1122. X        /* resist the temptation to do ptr arithmetic */
  1123. X        STcmd = (char *)malloc(strlen(line) + 1);
  1124. X        for(i = 0,sptr = &line[0]; sptr != tptr; sptr++,i++)
  1125. X            STcmd[i] = *sptr;
  1126. X        STcmd[i] = '\0';
  1127. X        for(; *tptr == ' ' || *tptr == '\t'; tptr++);
  1128. X        if(*tptr == '\0')
  1129. X            STargs = NULL;
  1130. X        else {
  1131. X            STargs = (char *)malloc(strlen(tptr) + 2);
  1132. X/* first byte of STargs is the length of the string */
  1133. X            STargs[0] = strlen(tptr);
  1134. X            STargs[1] = NULL; /* fake it for strcat */
  1135. X            strcat(STargs,tptr);
  1136. X        }
  1137. X    }
  1138. X/*
  1139. X * before we issue the command look for the '.', if it's not there
  1140. X * try adding .prg, .tos and .ttp to see if they exist, if not
  1141. X * issue the command as is
  1142. X */
  1143. X    if((tptr = index(STcmd,'.')) == NULL) {
  1144. X         STwork = (char *)malloc(strlen(STcmd) + 4);
  1145. X         strcpy(STwork,STcmd);
  1146. X         strcat(STwork,".prg");
  1147. X         tptr = index(STwork,'.');
  1148. X         if(Fsfirst(1,STwork) != 0) { /* try .tos */
  1149. X             strcpy(tptr,".tos");
  1150. X             if(Fsfirst(1,STwork) != 0) { /* try .ttp */
  1151. X                 strcpy(tptr,".ttp");
  1152. X                 if(Fsfirst(1,STwork) != 0) /* never mind */
  1153. X                     *STwork = NULL;
  1154. X                 }
  1155. X             }
  1156. X     }
  1157. X     if(*STwork != NULL)
  1158. X            Pexec(LOAD_EXEC,STwork,STargs,STenv);         
  1159. X    else
  1160. X            Pexec(LOAD_EXEC,STcmd,STargs,STenv);
  1161. X    TTopen();
  1162. X        mlputs("\r\n\n[End]");                  /* Pause.               */
  1163. X        TTgetc();                 /* Pause.               */
  1164. X        sgarbf = TRUE;
  1165. X        return (TRUE);
  1166. X#endif
  1167. X#if     VMS
  1168. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  1169. X                return (s);
  1170. X        TTputc('\n');                /* Already have '\r'    */
  1171. X        TTflush();
  1172. X        s = sys(line);                          /* Run the command.     */
  1173. X        mlputs("\r\n\n[End]");                  /* Pause.               */
  1174. X        TTflush();
  1175. X        tgetc();
  1176. X        sgarbf = TRUE;
  1177. X        return (s);
  1178. X#endif
  1179. X#if     CPM
  1180. X        mlwrite("Not in CP/M-86");
  1181. X        return (FALSE);
  1182. X#endif
  1183. X#if     MSDOS
  1184. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  1185. X                return(s);
  1186. X    movecursor(term.t_nrow - 1, 0);
  1187. X    TTkclose();
  1188. X        system(line);
  1189. X    TTkopen();
  1190. X    /* if we are interactive, pause here */
  1191. X    if (clexec == FALSE) {
  1192. X            mlputs("\r\n\n[End]");
  1193. X            tgetc();
  1194. X        }
  1195. X        sgarbf = TRUE;
  1196. X        return (TRUE);
  1197. X#endif
  1198. X#if     V7 | USG | BSD
  1199. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  1200. X                return (s);
  1201. X        TTputc('\n');                /* Already have '\r'    */
  1202. X        TTflush();
  1203. X        TTclose();                              /* stty to old modes    */
  1204. X        system(line);
  1205. X        TTopen();
  1206. X        mlputs("[End]");                        /* Pause.               */
  1207. X        TTflush();
  1208. X        while ((s = tgetc()) != '\r' && s != ' ')
  1209. X                ;
  1210. X        sgarbf = TRUE;
  1211. X        return (TRUE);
  1212. X#endif
  1213. X}
  1214. X
  1215. X/*
  1216. X * Pipe a one line command into a window
  1217. X * Bound to ^X @
  1218. X */
  1219. Xpipe(f, n)
  1220. X{
  1221. X        register int    s;    /* return status from CLI */
  1222. X    register WINDOW *wp;    /* pointer to new window */
  1223. X    register BUFFER *bp;    /* pointer to buffer to zot */
  1224. X        char    line[NLINE];    /* command line send to shell */
  1225. X    static char bname[] = "command";
  1226. X
  1227. X#if    AMIGA
  1228. X    static char filnam[] = "ram:command";
  1229. X        long newcli;
  1230. X#else
  1231. X    static char filnam[] = "command";
  1232. X#endif
  1233. X
  1234. X#if    MSDOS
  1235. X    char *tmp;
  1236. X    char *getenv();
  1237. X    FILE *fp;
  1238. X    FILE *fopen();
  1239. X#endif
  1240. X
  1241. X    /* don't allow this command if restricted */
  1242. X    if (restflag)
  1243. X        return(resterr());
  1244. X
  1245. X#if    MSDOS
  1246. X    if ((tmp = getenv("TMP")) == NULL)
  1247. X        strcpy(filnam, "command");
  1248. X    else
  1249. X        strcpy(filnam, tmp);
  1250. X#endif
  1251. X
  1252. X#if     VMS
  1253. X    mlwrite("Not availible under VMS");
  1254. X    return(FALSE);
  1255. X#endif
  1256. X#if     CPM
  1257. X        mlwrite("Not availible under CP/M-86");
  1258. X        return(FALSE);
  1259. X#endif
  1260. X
  1261. X    /* get the command to pipe in */
  1262. X        if ((s=mlreply("@", line, NLINE)) != TRUE)
  1263. X                return(s);
  1264. X
  1265. X    /* get rid of the command output buffer if it exists */
  1266. X        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  1267. X        /* try to make sure we are off screen */
  1268. X        wp = wheadp;
  1269. X        while (wp != NULL) {
  1270. X            if (wp->w_bufp == bp) {
  1271. X                onlywind(FALSE, 1);
  1272. X                break;
  1273. X            }
  1274. X            wp = wp->w_wndp;
  1275. X        }
  1276. X        if (zotbuf(bp) != TRUE)
  1277. X            return(FALSE);
  1278. X    }
  1279. X
  1280. X#if     AMIGA
  1281. X        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
  1282. X    strcat(line, " >");
  1283. X    strcat(line, filnam);
  1284. X        Execute(line,0,newcli);
  1285. X    s = TRUE;
  1286. X        Close(newcli);
  1287. X        sgarbf = TRUE;
  1288. X#endif
  1289. X#if     MSDOS
  1290. X    strcat(line," >>");
  1291. X    strcat(line,filnam);
  1292. X    movecursor(term.t_nrow - 1, 0);
  1293. X    TTkclose();
  1294. X        system(line);
  1295. X    TTkopen();
  1296. X        sgarbf = TRUE;
  1297. X    if ((fp = fopen(filnam, "r")) == NULL) {
  1298. X        s = FALSE;
  1299. X    } else {
  1300. X        fclose(fp);
  1301. X        s = TRUE;
  1302. X    }
  1303. X#endif
  1304. X#if     V7 | USG | BSD
  1305. X        TTputc('\n');                /* Already have '\r'    */
  1306. X        TTflush();
  1307. X        TTclose();                              /* stty to old modes    */
  1308. X    strcat(line,">");
  1309. X    strcat(line,filnam);
  1310. X        system(line);
  1311. X        TTopen();
  1312. X        TTflush();
  1313. X        sgarbf = TRUE;
  1314. X        s = TRUE;
  1315. X#endif
  1316. X
  1317. X    if (s != TRUE)
  1318. X        return(s);
  1319. X
  1320. X    /* split the current window to make room for the command output */
  1321. X    if (splitwind(FALSE, 1) == FALSE)
  1322. X            return(FALSE);
  1323. X
  1324. X    /* and read the stuff in */
  1325. X    if (getfile(filnam, FALSE) == FALSE)
  1326. X        return(FALSE);
  1327. X
  1328. X    /* make this window in VIEW mode, update all mode lines */
  1329. X    curwp->w_bufp->b_mode |= MDVIEW;
  1330. X    wp = wheadp;
  1331. X    while (wp != NULL) {
  1332. X        wp->w_flag |= WFMODE;
  1333. X        wp = wp->w_wndp;
  1334. X    }
  1335. X
  1336. X    /* and get rid of the temporary file */
  1337. X    unlink(filnam);
  1338. X    return(TRUE);
  1339. X}
  1340. X
  1341. X/*
  1342. X * filter a buffer through an external DOS program
  1343. X * Bound to ^X #
  1344. X */
  1345. Xfilter(f, n)
  1346. X
  1347. X{
  1348. X        register int    s;    /* return status from CLI */
  1349. X    register BUFFER *bp;    /* pointer to buffer to zot */
  1350. X        char line[NLINE];    /* command line send to shell */
  1351. X    char tmpnam[NFILEN];    /* place to store real file name */
  1352. X    static char bname1[] = "fltinp";
  1353. X
  1354. X#if    AMIGA
  1355. X    static char filnam1[] = "ram:fltinp";
  1356. X    static char filnam2[] = "ram:fltout";
  1357. X        long newcli;
  1358. X#else
  1359. X    static char filnam1[] = "fltinp";
  1360. X    static char filnam2[] = "fltout";
  1361. X#endif
  1362. X
  1363. X    /* don't allow this command if restricted */
  1364. X    if (restflag)
  1365. X        return(resterr());
  1366. X
  1367. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  1368. X        return(rdonly());    /* we are in read only mode    */
  1369. X
  1370. X#if     VMS
  1371. X    mlwrite("Not availible under VMS");
  1372. X    return(FALSE);
  1373. X#endif
  1374. X#if     CPM
  1375. X        mlwrite("Not availible under CP/M-86");
  1376. X        return(FALSE);
  1377. X#endif
  1378. X
  1379. X    /* get the filter name and its args */
  1380. X        if ((s=mlreply("#", line, NLINE)) != TRUE)
  1381. X                return(s);
  1382. X
  1383. X    /* setup the proper file names */
  1384. X    bp = curbp;
  1385. X    strcpy(tmpnam, bp->b_fname);    /* save the original name */
  1386. X    strcpy(bp->b_fname, bname1);    /* set it to our new one */
  1387. X
  1388. X    /* write it out, checking for errors */
  1389. X    if (writeout(filnam1) != TRUE) {
  1390. X        mlwrite("[Cannot write filter file]");
  1391. X        strcpy(bp->b_fname, tmpnam);
  1392. X        return(FALSE);
  1393. X    }
  1394. X
  1395. X#if     AMIGA
  1396. X        newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW);
  1397. X    strcat(line, " <ram:fltinp >ram:fltout");
  1398. X        Execute(line,0,newcli);
  1399. X    s = TRUE;
  1400. X        Close(newcli);
  1401. X        sgarbf = TRUE;
  1402. X#endif
  1403. X#if     MSDOS
  1404. X    strcat(line," <fltinp >fltout");
  1405. X    movecursor(term.t_nrow - 1, 0);
  1406. X    TTkclose();
  1407. X        system(line);
  1408. X    TTkopen();
  1409. X        sgarbf = TRUE;
  1410. X    s = TRUE;
  1411. X#endif
  1412. X#if     V7 | USG | BSD
  1413. X        TTputc('\n');                /* Already have '\r'    */
  1414. X        TTflush();
  1415. X        TTclose();                              /* stty to old modes    */
  1416. X    strcat(line," <fltinp >fltout");
  1417. X        system(line);
  1418. X        TTopen();
  1419. X        TTflush();
  1420. X        sgarbf = TRUE;
  1421. X        s = TRUE;
  1422. X#endif
  1423. X
  1424. X    /* on failure, escape gracefully */
  1425. X    if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  1426. X        mlwrite("[Execution failed]");
  1427. X        strcpy(bp->b_fname, tmpnam);
  1428. X        unlink(filnam1);
  1429. X        unlink(filnam2);
  1430. X        return(s);
  1431. X    }
  1432. X
  1433. X    /* reset file name */
  1434. X    strcpy(bp->b_fname, tmpnam);    /* restore name */
  1435. X    bp->b_flag |= BFCHG;        /* flag it as changed */
  1436. X
  1437. X    /* and get rid of the temporary file */
  1438. X    unlink(filnam1);
  1439. X    unlink(filnam2);
  1440. X    return(TRUE);
  1441. X}
  1442. X
  1443. X#if     VMS
  1444. X/*
  1445. X * Run a command. The "cmd" is a pointer to a command string, or NULL if you
  1446. X * want to run a copy of DCL in the subjob (this is how the standard routine
  1447. X * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
  1448. X * and the way out, because DCL does not want the channel to be in raw mode.
  1449. X */
  1450. Xsys(cmd)
  1451. Xregister char   *cmd;
  1452. X{
  1453. X        struct  dsc$descriptor  cdsc;
  1454. X        struct  dsc$descriptor  *cdscp;
  1455. X        long    status;
  1456. X        long    substatus;
  1457. X        long    iosb[2];
  1458. X
  1459. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1460. X                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1461. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1462. X                return (FALSE);
  1463. X        cdscp = NULL;                           /* Assume DCL.          */
  1464. X        if (cmd != NULL) {                      /* Build descriptor.    */
  1465. X                cdsc.dsc$a_pointer = cmd;
  1466. X                cdsc.dsc$w_length  = strlen(cmd);
  1467. X                cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1468. X                cdsc.dsc$b_class   = DSC$K_CLASS_S;
  1469. X                cdscp = &cdsc;
  1470. X        }
  1471. X        status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
  1472. X        if (status != SS$_NORMAL)
  1473. X                substatus = status;
  1474. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1475. X                          newmode, sizeof(newmode), 0, 0, 0, 0);
  1476. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1477. X                return (FALSE);
  1478. X        if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
  1479. X                return (FALSE);
  1480. X        return (TRUE);
  1481. X}
  1482. X#endif
  1483. X
  1484. X#if    ~AZTEC & MSDOS
  1485. X
  1486. X/*
  1487. X * This routine, once again by Bob McNamara, is a C translation of the "system"
  1488. X * routine in the MWC-86 run time library. It differs from the "system" routine
  1489. X * in that it does not unconditionally append the string ".exe" to the end of
  1490. X * the command name. We needed to do this because we want to be able to spawn
  1491. X * off "command.com". We really do not understand what it does, but if you don't
  1492. X * do it exactly "malloc" starts doing very very strange things.
  1493. X */
  1494. Xsys(cmd, tail)
  1495. Xchar    *cmd;
  1496. Xchar    *tail;
  1497. X{
  1498. X#if MWC_86
  1499. X        register unsigned n;
  1500. X        extern   char     *__end;
  1501. X
  1502. X        n = __end + 15;
  1503. X        n >>= 4;
  1504. X        n = ((n + dsreg() + 16) & 0xFFF0) + 16;
  1505. X        return(execall(cmd, tail, n));
  1506. X#endif
  1507. X
  1508. X#if LATTICE
  1509. X        return(forklp(cmd, tail, (char *)NULL));
  1510. X#endif
  1511. X
  1512. X#if    MSC
  1513. X    return(spawnlp(P_WAIT, cmd, tail, NULL));
  1514. X#endif
  1515. X}
  1516. X#endif
  1517. X
  1518. X#if    MSDOS & LATTICE
  1519. X/*    System: a modified version of lattice's system() function
  1520. X        that detects the proper switchar and uses it
  1521. X        written by Dana Hogget                */
  1522. X
  1523. Xsystem(cmd)
  1524. X
  1525. Xchar *cmd;    /*  Incoming command line to execute  */
  1526. X
  1527. X{
  1528. X    char *getenv();
  1529. X    static char *swchar = "/C";    /*  Execution switch  */
  1530. X    union REGS inregs;    /*  parameters for dos call  */
  1531. X    union REGS outregs;    /*  Return results from dos call  */
  1532. X    char *shell;        /*  Name of system command processor  */
  1533. X    char *p;        /*  Temporary pointer  */
  1534. X    int ferr;        /*  Error condition if any  */
  1535. X
  1536. X    /*  get name of system shell  */
  1537. X    if ((shell = getenv("COMSPEC")) == NULL) {
  1538. X        return (-1);        /*  No shell located  */
  1539. X    }
  1540. X
  1541. X    p = cmd;
  1542. X    while (isspace(*p)) {        /*  find out if null command */
  1543. X        p++;
  1544. X    }
  1545. X
  1546. X    /**  If the command line is not empty, bring up the shell  **/
  1547. X    /**  and execute the command.  Otherwise, bring up the     **/
  1548. X    /**  shell in interactive mode.   **/
  1549. X
  1550. X    if (p && *p) {
  1551. X        /**  detect current switch character and us it  **/
  1552. X        inregs.h.ah = 0x37;    /*  get setting data  */
  1553. X        inregs.h.al = 0x00;    /*  get switch character  */
  1554. X        intdos(&inregs, &outregs);
  1555. X        *swchar = outregs.h.dl;
  1556. X        ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
  1557. X    } else {
  1558. X        ferr = forkl(shell, "command", (char *)NULL);
  1559. X    }
  1560. X
  1561. X    return (ferr ? ferr : wait());
  1562. X}
  1563. X#endif
  1564. X
  1565. END_OF_spawn.c
  1566. if test 16459 -ne `wc -c <spawn.c`; then
  1567.     echo shar: \"spawn.c\" unpacked with wrong size!
  1568. fi
  1569. # end of overwriting check
  1570. fi
  1571. echo shar: Extracting \"window.c\" \(18023 characters\)
  1572. if test -f window.c ; then 
  1573.   echo shar: Will not over-write existing file \"window.c\"
  1574. else
  1575. sed "s/^X//" >window.c <<'END_OF_window.c'
  1576. X/*
  1577. X * Window management. Some of the functions are internal, and some are
  1578. X * attached to keys that the user actually types.
  1579. X */
  1580. X
  1581. X#include        <stdio.h>
  1582. X#include        "estruct.h"
  1583. X#include    "edef.h"
  1584. X
  1585. X#if    MEGAMAX & ST520
  1586. Xoverlay    "window"
  1587. X#endif
  1588. X
  1589. X/*
  1590. X * Reposition dot in the current window to line "n". If the argument is
  1591. X * positive, it is that line. If it is negative it is that line from the
  1592. X * bottom. If it is 0 the window is centered (this is what the standard
  1593. X * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  1594. X */
  1595. Xreposition(f, n)
  1596. X    {
  1597. X    if (f == FALSE)    /* default to 0 to center screen */
  1598. X    n = 0;
  1599. X    curwp->w_force = n;
  1600. X    curwp->w_flag |= WFFORCE;
  1601. X    return (TRUE);
  1602. X    }
  1603. X
  1604. X/*
  1605. X * Refresh the screen. With no argument, it just does the refresh. With an
  1606. X * argument it recenters "." in the current window. Bound to "C-L".
  1607. X */
  1608. Xrefresh(f, n)
  1609. X    {
  1610. X    if (f == FALSE)
  1611. X        sgarbf = TRUE;
  1612. X    else
  1613. X        {
  1614. X        curwp->w_force = 0;             /* Center dot. */
  1615. X        curwp->w_flag |= WFFORCE;
  1616. X        }
  1617. X
  1618. X    return (TRUE);
  1619. X    }
  1620. X
  1621. X/*
  1622. X * The command make the next window (next => down the screen) the current
  1623. X * window. There are no real errors, although the command does nothing if
  1624. X * there is only 1 window on the screen. Bound to "C-X C-N".
  1625. X *
  1626. X * with an argument this command finds the <n>th window from the top
  1627. X *
  1628. X */
  1629. Xnextwind(f, n)
  1630. X
  1631. Xint f, n;    /* default flag and numeric argument */
  1632. X
  1633. X{
  1634. X    register WINDOW *wp;
  1635. X    register int nwindows;        /* total number of windows */
  1636. X
  1637. X    if (f) {
  1638. X
  1639. X        /* first count the # of windows */
  1640. X        wp = wheadp;
  1641. X        nwindows = 1;
  1642. X        while (wp->w_wndp != NULL) {
  1643. X            nwindows++;
  1644. X            wp = wp->w_wndp;
  1645. X        }
  1646. X
  1647. X        /* if the argument is negative, it is the nth window
  1648. X           from the bottom of the screen            */
  1649. X        if (n < 0)
  1650. X            n = nwindows + n + 1;
  1651. X
  1652. X        /* if an argument, give them that window from the top */
  1653. X        if (n > 0 && n <= nwindows) {
  1654. X            wp = wheadp;
  1655. X            while (--n)
  1656. X                wp = wp->w_wndp;
  1657. X        } else {
  1658. X            mlwrite("Window number out of range");
  1659. X            return(FALSE);
  1660. X        }
  1661. X    } else
  1662. X        if ((wp = curwp->w_wndp) == NULL)
  1663. X            wp = wheadp;
  1664. X    curwp = wp;
  1665. X    curbp = wp->w_bufp;
  1666. X    upmode();
  1667. X    return (TRUE);
  1668. X}
  1669. X
  1670. X/*
  1671. X * This command makes the previous window (previous => up the screen) the
  1672. X * current window. There arn't any errors, although the command does not do a
  1673. X * lot if there is 1 window.
  1674. X */
  1675. Xprevwind(f, n)
  1676. X{
  1677. X    register WINDOW *wp1;
  1678. X    register WINDOW *wp2;
  1679. X
  1680. X    /* if we have an argument, we mean the nth window from the bottom */
  1681. X    if (f)
  1682. X        return(nextwind(f, -n));
  1683. X
  1684. X    wp1 = wheadp;
  1685. X    wp2 = curwp;
  1686. X
  1687. X    if (wp1 == wp2)
  1688. X        wp2 = NULL;
  1689. X
  1690. X    while (wp1->w_wndp != wp2)
  1691. X        wp1 = wp1->w_wndp;
  1692. X
  1693. X    curwp = wp1;
  1694. X    curbp = wp1->w_bufp;
  1695. X    upmode();
  1696. X    return (TRUE);
  1697. X}
  1698. X
  1699. X/*
  1700. X * This command moves the current window down by "arg" lines. Recompute the
  1701. X * top line in the window. The move up and move down code is almost completely
  1702. X * the same; most of the work has to do with reframing the window, and picking
  1703. X * a new dot. We share the code by having "move down" just be an interface to
  1704. X * "move up". Magic. Bound to "C-X C-N".
  1705. X */
  1706. Xmvdnwind(f, n)
  1707. X
  1708. Xint n;
  1709. X
  1710. X{
  1711. X    return (mvupwind(f, -n));
  1712. X}
  1713. X
  1714. X/*
  1715. X * Move the current window up by "arg" lines. Recompute the new top line of
  1716. X * the window. Look to see if "." is still on the screen. If it is, you win.
  1717. X * If it isn't, then move "." to center it in the new framing of the window
  1718. X * (this command does not really move "."; it moves the frame). Bound to
  1719. X * "C-X C-P".
  1720. X */
  1721. Xmvupwind(f, n)
  1722. X    int n;
  1723. X    {
  1724. X    register LINE *lp;
  1725. X    register int i;
  1726. X
  1727. X    lp = curwp->w_linep;
  1728. X
  1729. X    if (n < 0)
  1730. X        {
  1731. X        while (n++ && lp!=curbp->b_linep)
  1732. X            lp = lforw(lp);
  1733. X        }
  1734. X    else
  1735. X        {
  1736. X        while (n-- && lback(lp)!=curbp->b_linep)
  1737. X            lp = lback(lp);
  1738. X        }
  1739. X
  1740. X    curwp->w_linep = lp;
  1741. X    curwp->w_flag |= WFHARD;            /* Mode line is OK. */
  1742. X
  1743. X    for (i = 0; i < curwp->w_ntrows; ++i)
  1744. X        {
  1745. X        if (lp == curwp->w_dotp)
  1746. X            return (TRUE);
  1747. X        if (lp == curbp->b_linep)
  1748. X            break;
  1749. X        lp = lforw(lp);
  1750. X        }
  1751. X
  1752. X    lp = curwp->w_linep;
  1753. X    i  = curwp->w_ntrows/2;
  1754. X
  1755. X    while (i-- && lp != curbp->b_linep)
  1756. X        lp = lforw(lp);
  1757. X
  1758. X    curwp->w_dotp  = lp;
  1759. X    curwp->w_doto  = 0;
  1760. X    return (TRUE);
  1761. X    }
  1762. X
  1763. X/*
  1764. X * This command makes the current window the only window on the screen. Bound
  1765. X * to "C-X 1". Try to set the framing so that "." does not have to move on the
  1766. X * display. Some care has to be taken to keep the values of dot and mark in
  1767. X * the buffer structures right if the distruction of a window makes a buffer
  1768. X * become undisplayed.
  1769. X */
  1770. Xonlywind(f, n)
  1771. X{
  1772. X        register WINDOW *wp;
  1773. X        register LINE   *lp;
  1774. X        register int    i;
  1775. X
  1776. X        while (wheadp != curwp) {
  1777. X                wp = wheadp;
  1778. X                wheadp = wp->w_wndp;
  1779. X                if (--wp->w_bufp->b_nwnd == 0) {
  1780. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  1781. X                        wp->w_bufp->b_doto  = wp->w_doto;
  1782. X                        wp->w_bufp->b_markp = wp->w_markp;
  1783. X                        wp->w_bufp->b_marko = wp->w_marko;
  1784. X                }
  1785. X                free((char *) wp);
  1786. X        }
  1787. X        while (curwp->w_wndp != NULL) {
  1788. X                wp = curwp->w_wndp;
  1789. X                curwp->w_wndp = wp->w_wndp;
  1790. X                if (--wp->w_bufp->b_nwnd == 0) {
  1791. X                        wp->w_bufp->b_dotp  = wp->w_dotp;
  1792. X                        wp->w_bufp->b_doto  = wp->w_doto;
  1793. X                        wp->w_bufp->b_markp = wp->w_markp;
  1794. X                        wp->w_bufp->b_marko = wp->w_marko;
  1795. X                }
  1796. X                free((char *) wp);
  1797. X        }
  1798. X        lp = curwp->w_linep;
  1799. X        i  = curwp->w_toprow;
  1800. X        while (i!=0 && lback(lp)!=curbp->b_linep) {
  1801. X                --i;
  1802. X                lp = lback(lp);
  1803. X        }
  1804. X        curwp->w_toprow = 0;
  1805. X        curwp->w_ntrows = term.t_nrow-1;
  1806. X        curwp->w_linep  = lp;
  1807. X        curwp->w_flag  |= WFMODE|WFHARD;
  1808. X        return (TRUE);
  1809. X}
  1810. X
  1811. X/*
  1812. X * Delete the current window, placing its space in the window above,
  1813. X * or, if it is the top window, the window below. Bound to C-X 0.
  1814. X */
  1815. X
  1816. Xdelwind(f,n)
  1817. X
  1818. Xint f, n;    /* arguments are ignored for this command */
  1819. X
  1820. X{
  1821. X    register WINDOW *wp;    /* window to recieve deleted space */
  1822. X    register WINDOW *lwp;    /* ptr window before curwp */
  1823. X    register int target;    /* target line to search for */
  1824. X
  1825. X    /* if there is only one window, don't delete it */
  1826. X    if (wheadp->w_wndp == NULL) {
  1827. X        mlwrite("Can not delete this window");
  1828. X        return(FALSE);
  1829. X    }
  1830. X
  1831. X    /* find window before curwp in linked list */
  1832. X    wp = wheadp;
  1833. X    lwp = NULL;
  1834. X    while (wp != NULL) {
  1835. X        if (wp == curwp)
  1836. X            break;
  1837. X        lwp = wp;
  1838. X        wp = wp->w_wndp;
  1839. X    }
  1840. X
  1841. X    /* find recieving window and give up our space */
  1842. X    wp = wheadp;
  1843. X    if (curwp->w_toprow == 0) {
  1844. X        /* find the next window down */
  1845. X        target = curwp->w_ntrows + 1;
  1846. X        while (wp != NULL) {
  1847. X            if (wp->w_toprow == target)
  1848. X                break;
  1849. X            wp = wp->w_wndp;
  1850. X        }
  1851. X        if (wp == NULL)
  1852. X            return(FALSE);
  1853. X        wp->w_toprow = 0;
  1854. X        wp->w_ntrows += target;
  1855. X    } else {
  1856. X        /* find the next window up */
  1857. X        target = curwp->w_toprow - 1;
  1858. X        while (wp != NULL) {
  1859. X            if ((wp->w_toprow + wp->w_ntrows) == target)
  1860. X                break;
  1861. X            wp = wp->w_wndp;
  1862. X        }
  1863. X        if (wp == NULL)
  1864. X            return(FALSE);
  1865. X        wp->w_ntrows += 1 + curwp->w_ntrows;
  1866. X    }
  1867. X
  1868. X    /* get rid of the current window */
  1869. X    if (--curwp->w_bufp->b_nwnd == 0) {
  1870. X        curwp->w_bufp->b_dotp = curwp->w_dotp;
  1871. X        curwp->w_bufp->b_doto = curwp->w_doto;
  1872. X        curwp->w_bufp->b_markp = curwp->w_markp;
  1873. X        curwp->w_bufp->b_marko = curwp->w_marko;
  1874. X    }
  1875. X    if (lwp == NULL)
  1876. X        wheadp = curwp->w_wndp;
  1877. X    else
  1878. X        lwp->w_wndp = curwp->w_wndp;
  1879. X    free((char *)curwp);
  1880. X    curwp = wp;
  1881. X    wp->w_flag |= WFHARD;
  1882. X    curbp = wp->w_bufp;
  1883. X    upmode();
  1884. X    return(TRUE);
  1885. X}
  1886. X
  1887. X/*
  1888. X
  1889. XSplit the current window.  A window smaller than 3 lines cannot be
  1890. Xsplit.  An argument of 1 forces the cursor into the upper window, an
  1891. Xargument of two forces the cursor to the lower window.  The only other
  1892. Xerror that is possible is a "malloc" failure allocating the structure
  1893. Xfor the new window.  Bound to "C-X 2". 
  1894. X
  1895. X */
  1896. Xsplitwind(f, n)
  1897. X
  1898. Xint f, n;    /* default flag and numeric argument */
  1899. X
  1900. X{
  1901. X        register WINDOW *wp;
  1902. X        register LINE   *lp;
  1903. X        register int    ntru;
  1904. X        register int    ntrl;
  1905. X        register int    ntrd;
  1906. X        register WINDOW *wp1;
  1907. X        register WINDOW *wp2;
  1908. X    char *malloc();
  1909. X
  1910. X        if (curwp->w_ntrows < 3) {
  1911. X                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  1912. X                return (FALSE);
  1913. X        }
  1914. X        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  1915. X                mlwrite("Cannot allocate WINDOW block");
  1916. X                return (FALSE);
  1917. X        }
  1918. X        ++curbp->b_nwnd;                        /* Displayed twice.     */
  1919. X        wp->w_bufp  = curbp;
  1920. X        wp->w_dotp  = curwp->w_dotp;
  1921. X        wp->w_doto  = curwp->w_doto;
  1922. X        wp->w_markp = curwp->w_markp;
  1923. X        wp->w_marko = curwp->w_marko;
  1924. X        wp->w_flag  = 0;
  1925. X        wp->w_force = 0;
  1926. X#if    COLOR
  1927. X    /* set the colors of the new window */
  1928. X    wp->w_fcolor = gfcolor;
  1929. X    wp->w_bcolor = gbcolor;
  1930. X#endif
  1931. X        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  1932. X        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  1933. X        lp = curwp->w_linep;
  1934. X        ntrd = 0;
  1935. X        while (lp != curwp->w_dotp) {
  1936. X                ++ntrd;
  1937. X                lp = lforw(lp);
  1938. X        }
  1939. X        lp = curwp->w_linep;
  1940. X        if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  1941. X                /* Old is upper window. */
  1942. X                if (ntrd == ntru)               /* Hit mode line.       */
  1943. X                        lp = lforw(lp);
  1944. X                curwp->w_ntrows = ntru;
  1945. X                wp->w_wndp = curwp->w_wndp;
  1946. X                curwp->w_wndp = wp;
  1947. X                wp->w_toprow = curwp->w_toprow+ntru+1;
  1948. X                wp->w_ntrows = ntrl;
  1949. X        } else {                                /* Old is lower window  */
  1950. X                wp1 = NULL;
  1951. X                wp2 = wheadp;
  1952. X                while (wp2 != curwp) {
  1953. X                        wp1 = wp2;
  1954. X                        wp2 = wp2->w_wndp;
  1955. X                }
  1956. X                if (wp1 == NULL)
  1957. X                        wheadp = wp;
  1958. X                else
  1959. X                        wp1->w_wndp = wp;
  1960. X                wp->w_wndp   = curwp;
  1961. X                wp->w_toprow = curwp->w_toprow;
  1962. X                wp->w_ntrows = ntru;
  1963. X                ++ntru;                         /* Mode line.           */
  1964. X                curwp->w_toprow += ntru;
  1965. X                curwp->w_ntrows  = ntrl;
  1966. X                while (ntru--)
  1967. X                        lp = lforw(lp);
  1968. X        }
  1969. X        curwp->w_linep = lp;                    /* Adjust the top lines */
  1970. X        wp->w_linep = lp;                       /* if necessary.        */
  1971. X        curwp->w_flag |= WFMODE|WFHARD;
  1972. X        wp->w_flag |= WFMODE|WFHARD;
  1973. X        return (TRUE);
  1974. X}
  1975. X
  1976. X/*
  1977. X * Enlarge the current window. Find the window that loses space. Make sure it
  1978. X * is big enough. If so, hack the window descriptions, and ask redisplay to do
  1979. X * all the hard work. You don't just set "force reframe" because dot would
  1980. X * move. Bound to "C-X Z".
  1981. X */
  1982. Xenlargewind(f, n)
  1983. X{
  1984. X        register WINDOW *adjwp;
  1985. X        register LINE   *lp;
  1986. X        register int    i;
  1987. X
  1988. X        if (n < 0)
  1989. X                return (shrinkwind(f, -n));
  1990. X        if (wheadp->w_wndp == NULL) {
  1991. X                mlwrite("Only one window");
  1992. X                return (FALSE);
  1993. X        }
  1994. X        if ((adjwp=curwp->w_wndp) == NULL) {
  1995. X                adjwp = wheadp;
  1996. X                while (adjwp->w_wndp != curwp)
  1997. X                        adjwp = adjwp->w_wndp;
  1998. X        }
  1999. X        if (adjwp->w_ntrows <= n) {
  2000. X                mlwrite("Impossible change");
  2001. X                return (FALSE);
  2002. X        }
  2003. X        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
  2004. X                lp = adjwp->w_linep;
  2005. X                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  2006. X                        lp = lforw(lp);
  2007. X                adjwp->w_linep  = lp;
  2008. X                adjwp->w_toprow += n;
  2009. X        } else {                                /* Shrink above.        */
  2010. X                lp = curwp->w_linep;
  2011. X                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  2012. X                        lp = lback(lp);
  2013. X                curwp->w_linep  = lp;
  2014. X                curwp->w_toprow -= n;
  2015. X        }
  2016. X        curwp->w_ntrows += n;
  2017. X        adjwp->w_ntrows -= n;
  2018. X        curwp->w_flag |= WFMODE|WFHARD;
  2019. X        adjwp->w_flag |= WFMODE|WFHARD;
  2020. X        return (TRUE);
  2021. X}
  2022. X
  2023. X/*
  2024. X * Shrink the current window. Find the window that gains space. Hack at the
  2025. X * window descriptions. Ask the redisplay to do all the hard work. Bound to
  2026. X * "C-X C-Z".
  2027. X */
  2028. Xshrinkwind(f, n)
  2029. X{
  2030. X        register WINDOW *adjwp;
  2031. X        register LINE   *lp;
  2032. X        register int    i;
  2033. X
  2034. X        if (n < 0)
  2035. X                return (enlargewind(f, -n));
  2036. X        if (wheadp->w_wndp == NULL) {
  2037. X                mlwrite("Only one window");
  2038. X                return (FALSE);
  2039. X        }
  2040. X        if ((adjwp=curwp->w_wndp) == NULL) {
  2041. X                adjwp = wheadp;
  2042. X                while (adjwp->w_wndp != curwp)
  2043. X                        adjwp = adjwp->w_wndp;
  2044. X        }
  2045. X        if (curwp->w_ntrows <= n) {
  2046. X                mlwrite("Impossible change");
  2047. X                return (FALSE);
  2048. X        }
  2049. X        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
  2050. X                lp = adjwp->w_linep;
  2051. X                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  2052. X                        lp = lback(lp);
  2053. X                adjwp->w_linep  = lp;
  2054. X                adjwp->w_toprow -= n;
  2055. X        } else {                                /* Grow above.          */
  2056. X                lp = curwp->w_linep;
  2057. X                for (i=0; i<n && lp!=curbp->b_linep; ++i)
  2058. X                        lp = lforw(lp);
  2059. X                curwp->w_linep  = lp;
  2060. X                curwp->w_toprow += n;
  2061. X        }
  2062. X        curwp->w_ntrows -= n;
  2063. X        adjwp->w_ntrows += n;
  2064. X        curwp->w_flag |= WFMODE|WFHARD;
  2065. X        adjwp->w_flag |= WFMODE|WFHARD;
  2066. X        return (TRUE);
  2067. X}
  2068. X
  2069. X/*    Resize the current window to the requested size    */
  2070. X
  2071. Xresize(f, n)
  2072. X
  2073. Xint f, n;    /* default flag and numeric argument */
  2074. X
  2075. X{
  2076. X    int clines;    /* current # of lines in window */
  2077. X    
  2078. X    /* must have a non-default argument, else ignore call */
  2079. X    if (f == FALSE)
  2080. X        return(TRUE);
  2081. X
  2082. X    /* find out what to do */
  2083. X    clines = curwp->w_ntrows;
  2084. X
  2085. X    /* already the right size? */
  2086. X    if (clines == n)
  2087. X        return(TRUE);
  2088. X
  2089. X    return(enlargewind(TRUE, n - clines));
  2090. X}
  2091. X
  2092. X/*
  2093. X * Pick a window for a pop-up. Split the screen if there is only one window.
  2094. X * Pick the uppermost window that isn't the current window. An LRU algorithm
  2095. X * might be better. Return a pointer, or NULL on error.
  2096. X */
  2097. XWINDOW  *
  2098. Xwpopup()
  2099. X{
  2100. X        register WINDOW *wp;
  2101. X
  2102. X        if (wheadp->w_wndp == NULL              /* Only 1 window        */
  2103. X        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
  2104. X                return (NULL);
  2105. X        wp = wheadp;                            /* Find window to use   */
  2106. X        while (wp!=NULL && wp==curwp)
  2107. X                wp = wp->w_wndp;
  2108. X        return (wp);
  2109. X}
  2110. X
  2111. Xscrnextup(f, n)        /* scroll the next window up (back) a page */
  2112. X
  2113. X{
  2114. X    nextwind(FALSE, 1);
  2115. X    backpage(f, n);
  2116. X    prevwind(FALSE, 1);
  2117. X}
  2118. X
  2119. Xscrnextdw(f, n)        /* scroll the next window down (forward) a page */
  2120. X
  2121. X{
  2122. X    nextwind(FALSE, 1);
  2123. X    forwpage(f, n);
  2124. X    prevwind(FALSE, 1);
  2125. X}
  2126. X
  2127. Xsavewnd(f, n)        /* save ptr to current window */
  2128. X
  2129. X{
  2130. X    swindow = curwp;
  2131. X    return(TRUE);
  2132. X}
  2133. X
  2134. Xrestwnd(f, n)        /* restore the saved screen */
  2135. X
  2136. X{
  2137. X    register WINDOW *wp;
  2138. X
  2139. X    /* find the window */
  2140. X    wp = wheadp;
  2141. X    while (wp != NULL) {
  2142. X        if (wp == swindow) {
  2143. X            curwp = wp;
  2144. X            curbp = wp->w_bufp;
  2145. X            upmode();
  2146. X            return (TRUE);
  2147. X        }
  2148. X        wp = wp->w_wndp;
  2149. X    }
  2150. X
  2151. X    mlwrite("[No such window exists]");
  2152. X    return(FALSE);
  2153. X}
  2154. X
  2155. Xnewsize(f, n)    /* resize the screen, re-writing the screen */
  2156. X
  2157. Xint f;    /* default flag */
  2158. Xint n;    /* numeric argument */
  2159. X
  2160. X{
  2161. X    WINDOW *wp;    /* current window being examined */
  2162. X    WINDOW *nextwp;    /* next window to scan */
  2163. X    WINDOW *lastwp;    /* last window scanned */
  2164. X    int lastline;    /* screen line of last line of current window */
  2165. X
  2166. X    /* if the command defaults, assume the largest */
  2167. X    if (f == FALSE)
  2168. X        n = term.t_mrow + 1;
  2169. X
  2170. X    /* make sure it's in range */
  2171. X    if (n < 3 || n > term.t_mrow + 1) {
  2172. X        mlwrite("%%Screen size out of range");
  2173. X        return(FALSE);
  2174. X    }
  2175. X
  2176. X    if (term.t_nrow == n - 1)
  2177. X        return(TRUE);
  2178. X    else if (term.t_nrow < n - 1) {
  2179. X
  2180. X        /* go to the last window */
  2181. X        wp = wheadp;
  2182. X        while (wp->w_wndp != NULL)
  2183. X            wp = wp->w_wndp;
  2184. X
  2185. X        /* and enlarge it as needed */
  2186. X        wp->w_ntrows = n - wp->w_toprow - 2;
  2187. X        wp->w_flag |= WFHARD|WFMODE;
  2188. X
  2189. X    } else {
  2190. X
  2191. X        /* rebuild the window structure */
  2192. X        nextwp = wheadp;
  2193. X        wp = NULL;
  2194. X        lastwp = NULL;
  2195. X        while (nextwp != NULL) {
  2196. X            wp = nextwp;
  2197. X            nextwp = wp->w_wndp;
  2198. X    
  2199. X            /* get rid of it if it is too low */
  2200. X            if (wp->w_toprow > n - 2) {
  2201. X
  2202. X                /* save the point/mark if needed */
  2203. X                if (--wp->w_bufp->b_nwnd == 0) {
  2204. X                    wp->w_bufp->b_dotp = wp->w_dotp;
  2205. X                    wp->w_bufp->b_doto = wp->w_doto;
  2206. X                    wp->w_bufp->b_markp = wp->w_markp;
  2207. X                    wp->w_bufp->b_marko = wp->w_marko;
  2208. X                }
  2209. X    
  2210. X                /* update curwp and lastwp if needed */
  2211. X                if (wp == curwp)
  2212. X                    curwp = wheadp;
  2213. X                    curbp = curwp->w_bufp;
  2214. X                if (lastwp != NULL)
  2215. X                    lastwp->w_wndp = NULL;
  2216. X
  2217. X                /* free the structure */
  2218. X                free((char *)wp);
  2219. X                wp = NULL;
  2220. X
  2221. X            } else {
  2222. X                /* need to change this window size? */
  2223. X                lastline = wp->w_toprow + wp->w_ntrows - 1;
  2224. X                if (lastline >= n - 2) {
  2225. X                    wp->w_ntrows = n - wp->w_toprow - 2;
  2226. X                    wp->w_flag |= WFHARD|WFMODE;
  2227. X                }
  2228. X            }
  2229. X    
  2230. X            lastwp = wp;
  2231. X        }
  2232. X    }
  2233. X
  2234. X    /* screen is garbage */
  2235. X    term.t_nrow = n - 1;
  2236. X    sgarbf = TRUE;
  2237. X    return(TRUE);
  2238. X}
  2239. X
  2240. Xnewwidth(f, n)    /* resize the screen, re-writing the screen */
  2241. X
  2242. Xint f;    /* default flag */
  2243. Xint n;    /* numeric argument */
  2244. X
  2245. X{
  2246. X    /* if the command defaults, assume the largest */
  2247. X    if (f == FALSE)
  2248. X        n = term.t_mcol;
  2249. X
  2250. X    /* make sure it's in range */
  2251. X    if (n < 10 || n > term.t_mcol) {
  2252. X        mlwrite("%%Screen width out of range");
  2253. X        return(FALSE);
  2254. X    }
  2255. X
  2256. X    /* otherwise, just re-width it (no big deal) */
  2257. X    term.t_ncol = n;
  2258. X    term.t_margin = n / 10;
  2259. X    term.t_scrsiz = n - (term.t_margin * 2);
  2260. X    curwp->w_flag |= WFHARD | WFMOVE;
  2261. X    sgarbf = TRUE;
  2262. X    return(TRUE);
  2263. X}
  2264. END_OF_window.c
  2265. if test 18023 -ne `wc -c <window.c`; then
  2266.     echo shar: \"window.c\" unpacked with wrong size!
  2267. fi
  2268. # end of overwriting check
  2269. fi
  2270. echo shar: End of archive 7 \(of 14\).
  2271. cp /dev/null ark7isdone
  2272. MISSING=""
  2273. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2274.     if test ! -f ark${I}isdone ; then
  2275.     MISSING="${MISSING} ${I}"
  2276.     fi
  2277. done
  2278. if test "${MISSING}" = "" ; then
  2279.     echo You have unpacked all 14 archives.
  2280.     echo "See the readme file"
  2281.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2282. else
  2283.     echo You still need to unpack the following archives:
  2284.     echo "        " ${MISSING}
  2285. fi
  2286. ##  End of shell archive.
  2287. exit 0
  2288.